
/**
 * @file SourceStream.cpp
 * This class synchronizes rinex observation data streams.
 */

#include "SourceStream.hpp"

using namespace std;
using namespace gpstk;
using namespace StringUtils;

#define debug 0

namespace gpstk
{
      // Add a rinex obs file to the network
      // @oFile   Rinex observation file name
    bool SourceStream::setRinexObsFile(const std::string& oFile)
    {
        try
        {
            // close first
            obsStream.close();

            // clear eobit/failbit
            obsStream.clear();

            // open the obs file
            obsStream.open(oFile, std::ios::in);

            // we must reset the Rinex3ObsStream for current new rinex file
            obsStream.headerRead = false;

            // read the header of the obs file
            Rinex3ObsHeader obsHeader;
            obsStream >> obsHeader;

            obsSource.type = SatIDsystem2SourceIDtype(obsHeader.fileSysSat);
            obsSource.sourceName = StringUtils::upperCase( obsHeader.markerName.substr(0,4));

            antType = obsHeader.antType;

            return true;
        }
        catch(...)
        {
            // Problem opening the file
            return false;
        }

    }  // End of method 'SourceStream::addRinexObsFile()'


      // Get epoch data of the network
      // @epoch     Epoch
      // @gData     Object hold epoch observation data of the network
    void SourceStream::readEpochData( const CommonTime& epoch,
                                      commonHeader& comHeader,
                                      gnssRinex& gData )
    {

        pAntexReader = comHeader.pAntexReader;

        // clear the data map
        gData.body.clear();

        gnssRinex gRin;
        try
        {
            streampos sp( obsStream.tellg() );
            do
            {
                if( (obsStream).peek() != EOF )
                {
                   (obsStream) >> gRin;
                }
                else
                {
                    break;
                }
            }
            while(gRin.header.epoch < epoch);


            if( gRin.header.epoch == epoch )
            {
                string antModel = gRin.header.srcAntType ;
                Antenna antenna;

                try
                {
                    antenna = pAntexReader->getAntenna(antModel);
                }
                catch(ObjectNotFound& notFound)
                {
                    // new antenna model
                    if(antModel.size() == 20)
                    {
                        antModel.replace(16,4,"NONE");
                    }
                    else
                    {
                        // Some stations has special format, so we just erase the
                        // last 'NONE' and find the antenna.2017-04-17
                        antModel.erase(antModel.size()-4,4);
                    }

                    // new receiver antenna with new antenna model
                    try
                    {
                        antenna = pAntexReader->getAntenna( antModel );
                    }
                    catch(ObjectNotFound& notFound)
                    {
                        (obsStream).close();
                    }
                }

                gRin.header.srcAntenna = antenna;

            }
            else if(gRin.header.epoch > epoch )
            {
                obsStream.seekg( sp );
            }

            // copy 'gRin' to 'gData'
            gData = gRin;

        }
        catch(...)
        {
            (obsStream).close();
        }

    }  // End of method 'SourceStream::readEpochData()'

}  // End of namespace gpstk
